const { sqlite, database } = require("../JDBC");
const { ipcMain } = require("electron");
const fs = require("fs");
const Path = require("path");

const windows = global.windows;

const zlib = require("zlib");
const Bitwise = require('../BitwiseBuffer'); //按位运算库
const pngBase = require('./pngBase');

const { println } = require("../Console");
const { Console } = require("console");
const { fileIsExist } = require("../Common")
const { Task } = require("../Task");
// const println = console.log;

/**
 * NPK和IMG的处理工具
 * 1 为其他模块提供查询，并返回base64格式的图片
 * 2 索引、模糊查找、增删改查、转png
 */

/**
 * NPK文件结构：
 * [NPK_Header: [校验字节]+[img数量n]  ] +  [NPK_Index]*n =>[img数据包]*n
 *  
 * img数据包结构
 * [nimgF_Header: [校验字节]+[png数量m] ] + [nimgF_index]*m =>[png数据包]*m
 * 
 */


//文件名解密 秘钥
const fileNameBuffer = Buffer.from([
    "puchikon@neople dungeon and fighter ",
    "DNFDNFDNFDNFDNFDNFDNFDNFDNFDNFDNF",
    "DNFDNFDNFDNFDNFDNFDNFDNFDNFDNFDNF",
    "DNFDNFDNFDNFDNFDNFDNFDNFDNFDNFDNF",
    "DNFDNFDNFDNFDNFDNFDNFDNFDNFDNFDNF",
    "DNFDNFDNFDNFDNFDNFDNFDNFDNFDNFDNF",
    "DNFDNFDNFDNFDNFDNFDNFDNFDNFDNFDNF",
    "DNFDNFDNFDNFDNFDNFDNF\x00",
].join(""));

//NPK文件头
class NPK_Header {
    /*string:*/flag = null;// 文件标识 "NeoplePack_Bill"  [16]
    /*int:*/count = 0;     // 包内文件的数目

    constructor(flag, count) {
        this.flag = flag;
        this.count = count;
    }
};

//NPK索引
class NPK_Index {
    /*int:*/offset = 0;  //uint32_t  文件的包内偏移量
    /*int:*/size = 0;    //unit32_t  文件的大小
    /*string:*/name = "";   //char[256] 文件名

    constructor(offset, size, name) {
        this.offset = offset;
        this.size = size;
        this.name = name;
    }
}

//IMG文件头
class Img_Header {
    /*string:*/flag = null; // 文件标石"Neople Img File" [16]
    /*int:*/size = 0;	// 索引表大小，以字节为单位
    /*int:*/unknown1 = 0;
    /*int:*/unknown2 = 0;
    /*int:*/count = 0;// 索引表数目

    /*int*/ offset = 0;   //在文件中的偏移位置，应该==npkIndex.offset
    /*string*/index_name = null;

    constructor(index_name, flag, size, count, offset) {
        this.index_name = index_name;
        this.flag = flag;
        this.size = size;
        this.count = count;
        this.offset = offset;
    }
};

//IMG索引
class Img_Index {
    /*int:*/dwType = 0;     //目前已知的类型有 0x0E=14(1555格式) 0x0F=15(4444格式) 0x10=16(8888格式) 0x11=17(引用型 dwCompress指向引用的index)
    /*int:*/dwCompress = 0; // 目前已知的类型有 0x06=6(zlib压缩) 0x05=5(未压缩)
    /*int:*/width = 0;        // 宽度
    /*int:*/height = 0;       // 高度
    /*int:*/size = 0;         // 压缩时size为压缩后大小，未压缩时size为转换成8888格式时占用的内存大小
    /*int:*/key_x = 0;        // X关键点，当前图片在整图中的X坐标
    /*int:*/key_y = 0;        // Y关键点，当前图片在整图中的Y坐标
    /*int:*/max_width = 0;    // 整图的宽度
    /*int:*/max_height = 0;   // 整图的高度，有此数据是为了对齐精灵

    /*boolean*/vaild = true; //是否校验成功
    /*string */index_name = null;
    /*int    */index = 0;
    /*int    */argb_offset = 0;    //argb在npk文件的偏移起始位置
    /*Buffer */argb = null;     //读取argb文件流(解压后)

    constructor(index_name, index) {
        this.index_name = index_name;
        this.index = index;
    }
};

//按阶段读取
const LOAD_STEP = {
    "START": 0, //未开始阶段
    "IMG": 1, //读取img列表
    "ARGB": 2,//读取纹理
    "PNG": 3,//转换成png实体类
}

//int32字节码 转10进制
//注意有符号最大21亿  无符号42亿，且没有负数
const hexInt32ToNum = (buffer) => {
    return parseInt(buffer.readUInt32LE(0).toString(10))
}

//字节转latin1
//并去掉多余的 \x00
const hexToLatin1 = (buffer) => {
    return buffer.toString("latin1").replace(/\x00/g, "");
}

//分段读取
//@param filepath
//@param start:int 开始位 按字节数
//@param end:int   结束位 [start,end]闭区间
const readStream = (filepath, start, end) => new Promise((res, rej) => {
    let data = "";

    const readStream = fs.createReadStream(filepath, {
        start,
        end,
    })

    /**
     * encoding支持类型：
     * ascii     --7 位 ASCII
     * utf8
     * base64
     * binary (=latin1 )   一字节编码 8位
     * hex                  16进制 4位
     */
    readStream.setEncoding('hex'); //读取编码为16进制

    readStream.on('data', chunk => {
        data += chunk;
    })
    readStream.on('end', () => {
        res(Buffer.from(data, "hex"));
    })
    readStream.on('error', err => {
        rej(err);
    })
})


const openNpkHandler = {}

//Start阶段
//读取 npkHeader和npkIndex
openNpkHandler[LOAD_STEP.START] = (cursor) => new Promise((res, rej) => {
    readStream(cursor.path, 0, 19).then(buffer => {
        //校验文件头
        let checkBuffer = Buffer.from("NeoplePack_Bill\x00"); //标准文件头
        let loadBuffer = buffer.slice(1 - 1, 16); //1-16字节

        if (loadBuffer.length < 16 || Buffer.compare(checkBuffer, loadBuffer) != 0) {
            return rej(`读取NPK失败,未通过NpkHeader文件校验:${cursor.path}`)
        }

        let count = parseInt(buffer.readUInt32LE(17 - 1).toString(10)); //17-20字节 4字节 uint32
        let npkHeader = new NPK_Header("NeoplePack_Bill", count);
        // console.log("解析了一个npkHeader", npkHeader);

        cursor.npkHeader = npkHeader; //游标

        //读取NpkIndex
        readStream(cursor.path, 20, 20 + 264 * npkHeader.count - 1).then(buffer => {

            if (buffer.length != 264 * npkHeader.count) {
                console.error("", buffer.length, 264 * npkHeader.count)
                return rej(`读取NPK失败,npkIndex校验失败:${cursor.path}`)
            }

            for (let i = 0; i < npkHeader.count; i++) {
                let start = 264 * i;
                let end = start + 264

                let loadBuffer = buffer.slice(start, end);

                let offsetBuffer = loadBuffer.slice(1 - 1, 4); //4字节 uint32
                let sizeBuffer = loadBuffer.slice(5 - 1, 8);   //4字节 uint32
                let nameBuffer = loadBuffer.slice(9 - 1, 264); //256字节 char[256]
                nameBuffer = Bitwise.xor(nameBuffer, fileNameBuffer);  //异或秘钥 得到name明文

                let npkIndex = new NPK_Index(
                    hexInt32ToNum(offsetBuffer), //offset
                    hexInt32ToNum(sizeBuffer),//size
                    hexToLatin1(nameBuffer) //name
                )

                cursor.npkIndexs[i] = npkIndex;//游标
                // console.warn("解析了一个NPK_Index", npkIndex);
            }

            // console.warn("LOAD_STEP.START 任务完成")
            return res(cursor);
        }).catch(e => {
            console.error("读取NpkIndex错误")
            console.error(e);
            rej(`读取NPK失败,读取NpkIndex错误:${e.toString()},${cursor.path}`)
        })

    }).catch(e => {
        console.error("读取NpkHeader错误")
        console.error(e);
        rej(`读取NPK失败,读取NpkHeader错误:${e.toString()},${cursor.path}`)
    })
});

//Img阶段
//读取 imgHeader和imgIndex 以及计算argb的offset
openNpkHandler[LOAD_STEP.IMG] = (cursor) => new Promise((res, rej) => {
    //定义一个任务对象（任务数量,完成时回调）
    let task = new Task(cursor.npkIndexs.length, (result) => {
        next(result);
    })

    for (let i = 0; i < cursor.npkIndexs.length; i++) {
        let npkIndex = cursor.npkIndexs[i];
        let start = npkIndex.offset;
        let end = start + (16 + 4 * 4) - 1;

        //读取imgHeader并校验
        readStream(cursor.path, start, end).then(buffer => {
            if (buffer.length != (end - start + 1)) {
                console.error("读取img数据包错误!", buffer.length, npkIndex.size);
                cursor.errors.push(`读取img数据包错误,跳过该数据包,${npkIndex.name}`);
                cursor.imgHeaders[i] = false;
                task.push(false);
                return;
            }

            //nif格式
            let checkBuffer = Buffer.from("Neople Img File\x00"); //[16]
            let loadBuffer = buffer.slice(1 - 1, 16);//1-16字节  16字节 char[16]

            if (loadBuffer.length != 16 || Buffer.compare(loadBuffer, checkBuffer) != 0) {
                console.error("解析img数据包失败!", loadBuffer.length, loadBuffer.toString(), checkBuffer.toString());
                cursor.errors.push(`解析img数据包失败,跳过该数据包,${npkIndex.name}`);
                cursor.imgHeaders[i] = false;
                task.push(false);
                return;
            }

            let imgHeader = new Img_Header(
                npkIndex.name,              //index_name
                "Neople Img File",          //flag
                parseInt(buffer.readUInt32LE(17 - 1).toString(10)),  //size   17-20 4字节 
                parseInt(buffer.readUInt32LE(29 - 1).toString(10)),  //count  29-32 4字节
                start                       //offset
            )
            // console.log("解析了一个NImgF_Header", imgHeader);
            cursor.imgHeaders[i] = imgHeader;

            //循环读取imgIndexs
            readStream(cursor.path, end, end + imgHeader.size).then(buffer => {
                if (buffer.length != imgHeader.size + 1) { //这里size要加1 不知道为什么
                    console.error("读取img数据包错误!", buffer.length, npkIndex.size);
                    cursor.errors.push(`读取img数据包错误,跳过该数据包,${npkIndex.name}`);
                    cursor.imgHeaders[i] = false;
                    task.push(false);
                    return;
                }

                // console.log("imgindexs buffer.length", buffer.length)

                //可能有跳过字段，每个imgIndexs大小是不固定的
                //用这个变量记录上次读取结束的位置
                let offsetPoint = 1;
                let imgIndexs = []; //记录下本次找到的imgIndex

                for (let j = 0; j < imgHeader.count; j++) {
                    let imgIndex = new Img_Index(imgHeader.index_name, j);//index_name,index
                    try {

                        imgIndex.dwType = buffer.readUInt32LE(offsetPoint).toString(10);
                        offsetPoint += 4;

                        imgIndex.dwCompress = buffer.readUInt32LE(offsetPoint);
                        offsetPoint += 4;

                        // console.log("开始读取属性", imgIndex.index_name, imgIndex.index, imgIndex.dwType, imgIndex.dwCompress)

                        if (imgIndex.dwType == 17) {
                            // 引用型，只有dwType,dwCompress两个数据
                            //dwCompress指向引用index
                            // console.log("imgIndex.dwType == 17","imgIndex.dwCompress",imgIndex.dwCompress,
                            //     "imgPath",imgIndex.index_name,"index",imgIndex.index);
                            //跳过

                        } else {
                            imgIndex.width = buffer.readUInt32LE(offsetPoint).toString(10);
                            imgIndex.width = parseInt(imgIndex.width);
                            offsetPoint += 4;

                            imgIndex.height = buffer.readUInt32LE(offsetPoint).toString(10);
                            imgIndex.height = parseInt(imgIndex.height);
                            offsetPoint += 4;

                            imgIndex.size = buffer.readUInt32LE(offsetPoint).toString(10);
                            imgIndex.size = parseInt(imgIndex.size);
                            offsetPoint += 4;

                            imgIndex.key_x = buffer.readUInt32LE(offsetPoint).toString(10);
                            imgIndex.key_x = parseInt(imgIndex.key_x);
                            offsetPoint += 4;

                            imgIndex.key_y = buffer.readUInt32LE(offsetPoint).toString(10);
                            imgIndex.key_y = parseInt(imgIndex.key_y);
                            offsetPoint += 4;

                            imgIndex.max_width = buffer.readUInt32LE(offsetPoint).toString(10);
                            imgIndex.max_width = parseInt(imgIndex.max_width);
                            offsetPoint += 4;

                            imgIndex.max_height = buffer.readUInt32LE(offsetPoint).toString(10);
                            imgIndex.max_height = parseInt(imgIndex.max_height);
                            offsetPoint += 4;
                        }

                        imgIndexs.push(imgIndex);
                        // console.log("解析了一个 NImgF_Index", JSON.stringify(imgIndex));

                    } catch (e) {
                        console.error(`解析NImgF_Index错误,${imgHeader.index_name}[${j}],${JSON.stringify(imgIndex)}`)
                        console.error(e)
                    }

                }//end for

                //计算offset
                //并添加到cursor.imgIndexs中
                {
                    //文件中 img数据包的位置+ imgHeader[16+4x4] + imgHeader.size+1 是第一张图片开始的位置
                    let startOffset = npkIndex.offset + 32 + imgHeader.size;
                    let lastOffset = startOffset;
                    imgIndexs.forEach((imgIndex, j) => {
                        imgIndex.argb_offset = lastOffset;
                        lastOffset += imgIndex.size;
                        cursor.imgIndexs.push(imgIndex);

                        //@TEST 校验一下 最大不能超过文件大小
                        // {
                        //     let fileStat = fs.statSync(cursor.path);
                        //     let fileSize = fileStat.size;

                        //     if (imgIndex.argb_offset + imgIndex.size > fileSize) {
                        //         console.log("超过了文件大小", imgIndex.index_name, imgIndex.index)
                        //         console.log("imgIndex.argb_offset+imgIndex.size =", imgIndex.argb_offset + imgIndex.size)
                        //         console.log("fileSize=", fileSize);
                        //     }

                        // }

                    });
                }//end calc offset

                //将引用类型替换为引用对象
                {
                    imgIndexs.filter(e => e.dwType == 17).forEach(imgIndex => {
                        if (imgIndex.dwCompress < imgIndexs.length) {
                            let refImgIndex = imgIndexs[imgIndex.dwCompress];

                            if (refImgIndex) {
                                Object.keys(refImgIndex)
                                    .filter(key => key != "index") //别把index也复制了
                                    .forEach(key => {
                                        imgIndex[key] = refImgIndex[key];
                                    })
                            }
                        }
                    })
                }

                //提交任务
                task.push(true);
            }).catch(e => {
                console.error("读取imgIndex错误", npkIndex)
                console.error(e);
                cursor.errors.push(`读取imgIndex错误,${npkIndex.name},${e.toString()}`)
                task.push(false);
            })
        }).catch(e => {
            console.error("读取imgHeader错误", npkIndex)
            console.error(e);
            cursor.errors.push(`读取imgHeader错误,${npkIndex.name},${e.toString()}`)
            task.push(false);
        })
    }

    const next = (result) => {
        if (result.length != cursor.npkIndexs.length) {
            console.error("loadImgNext wating:", result.length, cursor.npkIndexs.length)
            rej(`内部错误,task索引错误,请重新执行操作`);
            return;
        }

        //@TEST打印一下解析结果
        // {
        //     console.log("step.IMG结束, cursor.imgIndexs.length=", cursor.imgIndexs.length);
        //     console.log(cursor.errors);

        //     cursor.imgIndexs
        //         .sort((e1, e2) => {
        //             if (e1.index_name != e2.index_name) {
        //                 return e1.index_name.localeCompare(e2.index_name)
        //             }

        //             return e1.index - e2.index;
        //         })
        //         .forEach(ii => {
        //             console.log(JSON.stringify(ii))
        //             // console.log(ii);
        //         })

        // }
        console.warn("LOAD_STEP.IMG 任务完成")
        res(cursor);
    }
});

//Argb阶段
//读取ARGB 存入imgIndex中
openNpkHandler[LOAD_STEP.ARGB] = (cursor) => new Promise((res, rej) => {
    let task = new Task(cursor.imgIndexs.length, result => {
        next(result);
    })

    let compilted = 0;

    cursor.imgIndexs.forEach(imgIndex => {

        //如果是引用类型 
        //重设为引用对象
        if (imgIndex.dwType == 17) {
            let refImgIndexs = cursor.imgIndexs.filter(e => {
                return e.index_name == imgIndex.index_name && e.index == imgIndex.dwCompress;
            })

            if (refImgIndexs && refImgIndexs.length >= 1) {
                let refImgIndex = refImgIndexs[0];

                Object.keys(refImgIndex)
                    .filter(key => key != "index") //别把index也复制了
                    .forEach(key => {
                        imgIndex[key] = refImgIndex[key];
                    })

            } else {
                imgIndex.vaild = false;
                task.push(false);
                console.error(`读取argb失败,未发现引用对象,${imgIndex.index_name}[${imgIndex.index}]`)
                console.error(`imgIndex.dwType=${imgIndex.dwType},imgIndex.dwCompress=${imgIndex.dwCompress}`)
                cursor.errors.push(`读取argb失败,未发现引用对象,${imgIndex.index_name}[${imgIndex.index}]`);
                return;
            }
        }

        let start = imgIndex.argb_offset;
        let end = start + imgIndex.size - 1;

        readStream(cursor.path, start, end).then(buffer => {
            if (buffer.length != imgIndex.size) {
                imgIndex.vaild = false;
                task.push(false);
                console.error(`读取argb失败,错误的数据大小,${imgIndex.index_name}[${imgIndex.index}]`)
                console.error(`buffer.lengt=${buffer.length},imgIndex.size=${imgIndex.size + 1}`);
                cursor.errors.push(`读取argb失败,${imgIndex.index_name}[${imgIndex.index}]`);
                return;
            }

            // console.log("读取了一个argb,",`start=${start},end=${end},end-1=${end-1}`);
            // console.log("buffer.length=",buffer.length,"imgIndex.size=",imgIndex.size,"dwCompress=",imgIndex.dwCompress)

            if (imgIndex.dwCompress == 6) {
                //压缩数据

                zlib.inflate(buffer, (err, if_buffer) => {
                    if (err) {
                        console.error("解压错误", imgIndex);
                        console.error(err);
                        imgIndex.vaild = false;
                        cursor.errors.push(`读取argb失败,未能解压数据,"${imgIndex.index_name}[${imgIndex.index}]"`);
                        return task.push(false);//任务失败
                    }

                    // console.log("zlib:", "解压前大小:", imgIndex.argb.length, "解压后大小:", if_buffer.length);
                    imgIndex.argb = if_buffer;
                    imgIndex.dwCompress = 5; //设置成5  方便其他引用型判断

                    compilted++
                    return task.push(true); //任务完成
                })
            } else if (imgIndex.dwCompress == 5) {
                //未压缩
                imgIndex.argb = buffer;

                compilted++;
                return task.push(true); //任务完成

            } else {
                //其他
                console.error("未识别的索引类型")
                imgIndex.vaild = false;
                errors.push(`读取argb失败,未识别的索引类型,"${imgIndex.index_name}[${index}]", dwCompress=${imgIndex.dwCompress}`);
                return task.push(false); //任务完成
            }
        })

    })
    const next = (result) => {
        if (result.length != cursor.imgIndexs.length) {
            console.error("loadArgbNext wating:", result.length, cursor.npkHeader.count)
            rej(`内部错误,task索引错误,请重新执行操作`);
            return;
        }

        //@TEST打印一下解析结果
        // {
        //     console.log("step.ARGB结束", cursor.imgIndexs.length, compilted);
        //     console.log(cursor.errors);

        //     cursor.imgIndexs
        //         .filter(e=> e.vaild)
        //         .sort((e1, e2) => {
        //             if (e1.index_name != e2.index_name) {
        //                 return e1.index_name.localeCompare(e2.index_name)
        //             }

        //             return e1.index - e2.index;
        //         })
        //         .forEach(ii => {
        //             let obj = {
        //                 dwType:ii.dwType,
        //                 dwCompress:ii.dwCompress,
        //                 index_name: ii.index_name,
        //                 index: ii.index,
        //                 argb_length: ii.argb.length
        //             }

        //             console.log(JSON.stringify(obj));
        //         })
        // }
        console.warn("LOAD_STEP.ARGB 任务完成")
        res(cursor);
    }
});

//Png阶段
//将Argb转成Png实体类
openNpkHandler[LOAD_STEP.PNG] = (cursor) => new Promise((res, rej) => {
    let task = new Task(cursor.imgIndexs.length, result => {
        next(result);
    })

    cursor.imgIndexs.forEach(imgIndex => {
        if (imgIndex.vaild != true) {
            console.error(`读取png失败，未通过校验的imgIndex,跳过该任务，${imgIndex.index_name}[${imgIndex.index}]`);
            cursor.errors.push(`读取png失败，未通过校验的imgIndex,跳过该任务，${imgIndex.index_name}[${imgIndex.index}]`)
            return task.push(false);
        }

        pngBase.getPngFile(imgIndex, imgIndex.argb)
            .then(png => {
                cursor.imgPngs.push({
                    path: imgIndex.index_name,
                    index: imgIndex.index,
                    png: png,
                })

                task.push(true);//提交任务
            })
            .catch(e => {
                console.error("argb转png失败!", `${imgIndex.index_name}[${imgIndex.index}]`)
                console.error(e)
                cursor.errors.push(`argb转png失败,"${imgIndex.index_name}[${imgIndex.index}]",${e.toString}`);
                imgIndex.vaild = false;
                task.push(false);
            })
    });


    const next = (result) => {
        if (result.length != cursor.imgIndexs.length) {
            console.error("loadPngNext wating:", result.length, cursor.npkHeader.count)
            rej(`内部错误,task索引错误,请重新执行操作`);
            return;
        }

        //@TEST打印一下解析结果
        // {
        //     console.log("stepPNG结束", cursor.imgIndexs.length, cursor.imgPngs.length);
        //     console.log(cursor.errors);

        //     cursor.imgPngs
        //         .sort((e1, e2) => {
        //             if (e1.path != e2.path) {
        //                 return e1.path.localeCompare(e2.path)
        //             }

        //             return e1.index - e2.index;
        //         })
        //         .forEach(ip => {
        //             let obj = {
        //                 path: ip.path,
        //                 index: ip.index,
        //                 png: typeof (ip.png)
        //             }
        //             console.log(JSON.stringify(obj));
        //         })
        // }
        console.warn("LOAD_STEP.PNG任务完成")
        res(cursor);
    }
});


/* 读取npk文件 */
//@param path:string 文件路径
//@param step:LOAD_STEP  处理到哪个阶段
const openNpkProxy = (path, step) => {
    console.log("openNpkProxy");
    if (!fileIsExist(path)) {
        console.error(`读取NPK失败,未找到文件:${path}`);
        return new Promise((res, rej) => {
            rej(`读取NPK失败,未找到文件:${path}`)
        })
    }

    let cursor = {
        path,
        step: LOAD_STEP.START,
        npkHeader: null,  //count对应npkIndexs.length
        npkIndexs: [],
        imgHeaders: [], //count对应imgIndexs.length  注意数组索引顺序
        imgIndexs: [],  //无序数组，用的时候根据index_name和index取
        imgPngs: [],  //{path,index,png}
        errors: [],
    }

    return new Promise((res, rej) => {
        const next = () => {
            openNpkHandler[cursor.step](cursor).then(() => {
                if (step >= cursor.step + 1) {
                    cursor.step++;
                    next(); //继续下一阶段
                    return;
                }

                if (step < cursor.step + 1) {
                    console.log("openNpkProxy 已完成任务")
                    return res(cursor); //完成，返回
                }
            }).catch(e => {
                rej(e);
            })
        }
        next();
    })
}

/* 读取npk下指定img的所有base64 */
//@param path:string
//@param img:string
//@param callback: function(err,data)  转出一条执行一次   只有停止任务的错误才调用callback(err) 普通错误用callback(null,data{error})
const openNpkImgAll = (path, img, callback) => {
    console.log("openNpkImgAll");

    if (!fileIsExist(path)) {
        console.error(`读取NPK失败,未找到文件:${path}`);
        callback(`读取NPK失败,未找到文件:${path}`)
        return;
    }

    let cursor = {
        path,
        step: LOAD_STEP.START,
        npkHeader: null,  //count对应npkIndexs.length
        npkIndexs: [],
        imgHeaders: [], //count对应imgIndexs.length  注意数组索引顺序
        imgIndexs: [],  //无序数组，用的时候根据index_name和index取
        imgPngs: [],  //{path,index,png}
        errors: [],
    }

    const next = () => {
        openNpkHandler[cursor.step](cursor).then(() => {
            if (cursor.step == LOAD_STEP.START) {
                //过滤出需要的imgPath
                cursor.npkIndexs = cursor.npkIndexs.filter(e => {
                    return e.name == img;
                })
            }

            if (cursor.step < LOAD_STEP.PNG) {
                cursor.step++;
                next(); //继续下一阶段
                return;
            }

            if (cursor.step >= LOAD_STEP.PNG) {
                toBase64();
            }
        }).catch(e => {
            console.error(`任务失败:${path}`,e);
            callback(e)
        })
    }

    const toBase64 = () => {
        //返回第一条消息  base64数量
        callback(null, { count: cursor.imgPngs.length });

        cursor.imgPngs.forEach(pngs => {
            let png = pngs.png;
            png.getBase64Async("image/png")
                .then(base64 => {
                    console.log("返回一条base64")
                    callback(null, {
                        index: pngs.index,
                        base64,
                    })

                }).catch(e => {
                    console.log("转base64失败，返回错误消息")
                    callback(null, {
                        index: pngs.index,
                        error: e.toString()
                    });
                });
        })
    }

    next();
}


/* 读取npk下指定img下指定索引base64 */
const openNpkImgIndex = (path, img, index, callback) => {
    console.log("openNpkImgIndex");

    if (!fileIsExist(path)) {
        console.error(`读取NPK失败,未找到文件:${path}`);
        return new Promise((res, rej) => {
            rej(`读取NPK失败,未找到文件:${path}`)
        })
    }

    let cursor = {
        path,
        step: LOAD_STEP.START,
        npkHeader: null,  //count对应npkIndexs.length
        npkIndexs: [],
        imgHeaders: [], //count对应imgIndexs.length  注意数组索引顺序
        imgIndexs: [],  //无序数组，用的时候根据index_name和index取
        imgPngs: [],  //{path,index,png}
        errors: [],
    }

    const next = () => {
        openNpkHandler[cursor.step](cursor).then(() => {
            if (cursor.step == LOAD_STEP.START) {
                //过滤出需要的imgPath
                cursor.npkIndexs = cursor.npkIndexs.filter(e => {
                    return e.name == img;
                })
            }

            if (cursor.step == LOAD_STEP.IMG) {
                //过滤出需要的index
                cursor.imgIndexs = cursor.imgIndexs.filter(e => {
                    return e.index == index;
                })
            }

            if (cursor.step < LOAD_STEP.PNG) {
                cursor.step++;
                next(); //继续下一阶段
                return;
            }

            if (cursor.step >= LOAD_STEP.PNG) {
                toBase64();
            }
        }).catch(e => {
            rej(e);
        })
    }

    const toBase64 = () => {

        cursor.imgPngs.forEach(pngs => {
            let png = pngs.png;
            png.getBase64Async("image/png")
                .then(base64 => {
                    console.log("返回一条base64")
                    callback(null, {
                        index: pngs.index,
                        base64,
                    })

                }).catch(e => {
                    // console.log("转base64失败，返回错误消息")
                    callback(e, null);
                });
        })
    }

    next();
}



module.exports = {
    openNpk: openNpkProxy,
    openNpkImgAll,
    openNpkImgIndex,
    LOAD_STEP,
}